package com.sduept.nwld.fault.handler;

import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.manager.FaultRecordDetectionQueryManager;
import com.sduept.bigdata.fault.manager.FaultRecordQueryManager;
import com.sduept.cim.ledger.excetpion.ManagementUnitException;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.cim.ledger.model.ManagementUnitDict;
import com.sduept.core.ParamManager;
import com.sduept.core.dao.SuperDAO;
import com.sduept.core.entity.SystemParameter;
import com.sduept.message.queue.DelayQueueMessage;
import com.sduept.message.queue.DelayQueueService;
import com.sduept.message.queue.DelayQueueTimeoutHandler;
import com.sduept.nwld.dataserver.manager.message.MosMessagePushManager;
import com.sduept.permission.entity.DepartmentEntityBean;
import com.sduept.permission.entity.PersonnelEntityBean;
import com.sduept.permission.entity.RoleEntityBean;
import com.sduept.permission.manager.DepartManager;
import com.sduept.permission.manager.RoleManager;
import com.sduept.utils.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.Map.Entry;

/**
 * 超时处理handler
 * @author 
 *
 */
@Slf4j
public class MessageTimeOutHandler implements DelayQueueTimeoutHandler {
	private ParamManager pcache = SpringContext.getBean(ParamManager.class);
	private SuperDAO dao = SpringContext.getBean(SuperDAO.class);
	private DepartManager dm = SpringContext.getBean(DepartManager.class);
	private RoleManager rm = SpringContext.getBean(RoleManager.class);
	private SubstationLedgerManager slm = SpringContext.getBean(SubstationLedgerManager.class);
	private MosMessagePushManager mmpm = SpringContext.getBean(MosMessagePushManager.class);
	private DelayQueueService queueService = SpringContext.getBean(DelayQueueService.class);//队列消费者
	private FaultRecordDetectionQueryManager fdqm = SpringContext.getBean(FaultRecordDetectionQueryManager.class);
	private FaultRecordQueryManager frqm = SpringContext.getBean(FaultRecordQueryManager.class);
	private static final String fault_detect_time_interval = "fault_detect_time_interval";
	@Override
	public void handlerAfterTimeout(DelayQueueMessage queueMessage)  {
		String faultId = queueMessage.getMessageId();
		FaultRecord fr = frqm.findById(faultId);
		if(fr==null||fr.getStatus()==1) {
			return ;
		}
		String message = detectMessage(faultId,fr);
		long lastTime = queueMessage.getDelayTime();
		boolean messageStatus = chargeSendStatus(message);//判断是否继续发送消息
		if(messageStatus) {
			SystemParameter param = pcache.get(fault_detect_time_interval);
			message=message.replaceAll("#\\{发送\\}", "");
			List<String> phones = getPhoneListByFaultId(faultId);
			if(CollectionUtils.isEmpty(phones)) {
				log.error("未找到可接受短信的保护专责人员电话，请联系管理员！");
			}else {
				try {
					mmpm.sendMsgByMass(phones, queueMessage.getName(), message);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			String[] interval = param.getValue().split(",");
			for (int i = 0; i < interval.length; i++) {//间隔可变
				int timeTem = Integer.valueOf(interval[i])*1000;
				int finalTime = Integer.valueOf(interval[interval.length-1])*1000;
				if(lastTime==timeTem && lastTime!=finalTime) {
					int nextTime = Integer.valueOf(interval[i+1]);
					long delayTime = nextTime*1000;
					offerDelayTime(delayTime,queueMessage);
					break;
				}
			}
		}
	}	
	
	
	
	/**
	 *设置消息所需内容向队列添加延迟消息
	 * @param delayTime
	 * @param queueMessage 
	 * @param faultId
	 * @param title
	 * @param handler
	 */
	private void offerDelayTime(long delayTime, DelayQueueMessage queueMessage) {
		queueMessage.setId(null);
		queueMessage.setDelayTime(delayTime);
		//queueMessage.setStartTime(System.currentTimeMillis());
		queueMessage.setExpireTime(queueMessage.getDelayTime()+queueMessage.getStartTime());
		queueMessage.setStatus(0);
		queueService.offerDelayQueueAndCheckOnly(queueMessage);
	}
	


	/**
	 * 根据故障id查找设备->查找对应的站->对应的运维单位->有保护专责角色的人的电话
	 * @param faultId
	 * @return
	 */
	private List<String> getPhoneListByFaultId(String faultId) {
		FaultRecord fr = frqm.findById(faultId);
		if(fr==null) 
			return new ArrayList<>();
        List<String> stationIds = new ArrayList<>();
		if(StringUtils.isNotBlank(fr.getStationId())) {//变电站id不为空 查找运维单位
			stationIds.add(fr.getStationId());
		}
		if(StringUtils.isNotBlank(fr.getStationId2())) {
			stationIds.add(fr.getStationId2());
		}
		Map<String,List<PersonnelEntityBean>> map = getUnitAndPersonMap();
		List<String> phones = getPhonesByStationAndUnitPersonMap(stationIds,map);
		return phones;
	}
	/**
	 * 根据拥有保护专责角色的人员 组合成Map key:人员所属单位  value:人员
	 * @return
	 */
	private Map<String, List<PersonnelEntityBean>> getUnitAndPersonMap() {
		Map<String, List<PersonnelEntityBean>> map = new HashMap<String, List<PersonnelEntityBean>>();
		 List<PersonnelEntityBean> persons = null;
		 String roleName = "保护专责";
		 String roleId = findRoleIdByRoleName(roleName);
		 try {
			persons = rm.findRolePersonnels(roleId);//拥有保护专责角色的人
		} catch (Exception e) {
			log.error("没有拥有保护专责角色的人员");
			e.printStackTrace();
		}
		 for (PersonnelEntityBean per : persons) {
				List<DepartmentEntityBean> departs = new ArrayList<DepartmentEntityBean>();
				DepartmentEntityBean depart = per.getGroup();
				departs = dm.recursiveFindParentDepartments(depart);
				departs.add(depart);
				StringBuilder build = new StringBuilder();
				for (DepartmentEntityBean dept : departs) {
					build.append(dept.getName()+" ");
				}
				List<PersonnelEntityBean> value = map.get(build.toString());
				if(CollectionUtils.isEmpty(value)) {
					value = new ArrayList<>();
				}
				map.put(build.toString(), value);
				value.add(per);
		}
		return map;
	}
	
	/**
	 * 根据角色名称获取角色id
	 * @param roleName
	 * @return
	 */
	private String findRoleIdByRoleName(String roleName) {
		 List<RoleEntityBean> roles = dao.findByCondition(RoleEntityBean.class, " name =? ", roleName);
		 if(CollectionUtils.isEmpty(roles)) {
			 return "";
		 }
		return roles.get(0).getId();
	}
	/**
	 * 根据变电站id->运维单位->具有保护专责角色人员的电话
	 * @param stationIds
	 * @param map 
	 * @return
	 */
	private List<String> getPhonesByStationAndUnitPersonMap(List<String> stationIds, Map<String,List<PersonnelEntityBean>> map) {
		List<String> phones = new ArrayList<>();
		ManagementUnitDict mud = null;
		for (String stationId : stationIds) {
			 try {
				mud = slm.getMaintanceUnitByStationId(stationId);//根据站查找运维单位
			} catch (ManagementUnitException e) {
				e.printStackTrace();
			}
			 if(mud==null) {
					continue;
				}
			for(Entry<String, List<PersonnelEntityBean>> entry:map.entrySet()) {
				if(entry.getKey().contains(mud.getName())) {
					for (PersonnelEntityBean per : entry.getValue()) {
						phones.add(per.getTelephone());
					}
					
				}
			}
		}
		return phones;
	}
	/**
	 * 根据拼接的短信内容判断发送状态
	 * @param message
	 * @return
	 */
	private boolean chargeSendStatus(String message) {
		if(message.contains("#{发送}")) {
			return true;
		}else {
			return false;
		}
	}
	/**
	 * 根据故障ID获得检测信息
	 * @param faultId
	 * @param fr 
	 * @return
	 */
	private String detectMessage(String faultId, FaultRecord fr) {
        String messageTemplate = "#{时间}，#{设备}跳闸，保护大数据系统中#{内容}资料未填报或未填报完整，请补报。";
        StringBuilder specific = new StringBuilder();
        messageTemplate = replaceTimeAndEquipmentName(fr, messageTemplate);
        specific = buildMessageByDetectResult(faultId,specific)  ;  
        messageTemplate = messageTemplate.replace("#{内容}", specific.toString());
		return messageTemplate;
	}
	  /**
	   * 根据故障资料完整度拼接短信内容
	   * @param faultId
	   * @param specific
	   * @return
	   */
	 private StringBuilder buildMessageByDetectResult(String faultId, StringBuilder specific) {
			if(fdqm.getDetectForActionEvent(faultId).getStatus()!=1) {
		    	specific.append("动作事件#{发送}");
		    }
		    if(fdqm.getDetectForCentralWave(faultId).getStatus()!=1) {
		    	specific.append("，集中录波源文件#{发送}");
		    }
		    if(fdqm.getDetectForProtectionWave(faultId).getStatus()!=1||fdqm.getDetectForBreakerProtectionWave(faultId).getStatus()!=1) {
		    	specific.append("，保护录波源文件#{发送}");
		    }
		    if(specific.toString().contains("保护录波源文件#{发送}")) {
		    	if(fdqm.getDetectForAttachment(faultId).getStatus()!=1) {
					specific.append("，录波扫描件#{发送}");
				}
		    }
			return specific;
		}
		/**
		 * 根据故障信息替换时间和设备名称
		 * @param fr
		 * @param messageTemplate 
		 */
		private String replaceTimeAndEquipmentName(FaultRecord fr, String messageTemplate) {
			Date date = fr.getFaultTime();
			Calendar clDate =Calendar.getInstance();
			clDate.setTime(date);
			int year = clDate.get(Calendar.YEAR);
			int month = clDate.get(Calendar.MONTH)+1;
			int day = clDate.get(Calendar.DAY_OF_MONTH);
			int hour = clDate.get(Calendar.HOUR_OF_DAY);
			int minute = clDate.get(Calendar.MINUTE);
			int second = clDate.get(Calendar.SECOND);
			String time = year+"年"+month+"月"+day+"日"+hour+"时"+minute+"分"+second+"秒";
			messageTemplate = messageTemplate.replace("#{时间}", time);
			return messageTemplate.replace("#{设备}", fr.getEquipment());
		  }
      }
